package io.gitee.itxinmeng.encrypt.spring.boot.common.encrypt.strategy.impl;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.json.JSONUtil;
import io.gitee.itxinmeng.encrypt.spring.boot.autoconfigure.properties.EncryptProperties;
import io.gitee.itxinmeng.encrypt.spring.boot.common.encrypt.EncryptMethodFactory;
import io.gitee.itxinmeng.encrypt.spring.boot.common.encrypt.strategy.IEncryptStrategy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;


/**
 * @author mx
 */
@Component
//@ConditionalOnProperty(prefix = "custom.encrypt", name = "method",havingValue = "AES")
public class AesEncryptStrategyImpl implements IEncryptStrategy, InitializingBean {
    private static final Logger LOGGER = LoggerFactory.getLogger(AesEncryptStrategyImpl.class);

    @Resource
    private EncryptProperties config;

    @Override
    public Object encryptBody(Object body, ServerHttpRequest request) {
        try {
            String content = JSONUtil.toJsonStr(body);
            byte[] data = content.getBytes(StandardCharsets.UTF_8);
            String respStr = "";
            // Aes 加密
            String aesKey = config.getSecret();
            Assert.notBlank(aesKey,"The secret are not exist!");
            respStr = SecureUtil.aes(aesKey.getBytes(StandardCharsets.UTF_8))
                    .encryptHex(data);
            if (LOGGER.isDebugEnabled()) {
                LOGGER.info("Before encrypt：({})，After encrypt：({})", content, respStr);
            }
            return respStr;
        } catch (Exception e) {
            LOGGER.error("Encrypt reponse error!", e);
            throw new RuntimeException(e.getMessage());
        }
    }

    @Override
    public String decryptBody(HttpHeaders headers, String content) {
        String secret = config.getSecret();
        Assert.notBlank(secret,"The secret are not exist!");
        String decryptContent = SecureUtil.aes(secret.getBytes(StandardCharsets.UTF_8))
                .decryptStr(content);
        return decryptContent;
    }

    @Override
    public Boolean check(){
        String secret = config.getSecret();
        return StrUtil.isBlank(secret) ? Boolean.FALSE : Boolean.TRUE;
    }

    @Override
    public void afterPropertiesSet() {
        EncryptMethodFactory.INSTANCE.addEncryptStrategy(EncryptMethodFactory.EncryptMethodEnum.AES,this);
    }
}
